package library

///
// Markdown 生成库
///
import (
	"bytes"
	"fmt"
	"os"
	"reflect"
	"runtime"
	"strings"
)

// Markdown 用于输出运行信息到 Markdown
type Markdown struct {
	Data *bytes.Buffer
}

// Init 初始化
func (M *Markdown) Init() {
	M.Data = bytes.NewBuffer([]byte{})
}

// AddTrace 添加追踪
func (M *Markdown) AddTrace() {
	// 获得调用栈信息
	N, _ := GetGid()
	M.Data.WriteString(fmt.Sprintf("# 函数名: %s  \n> GoroutineID: %d   \n# 调用栈信息: \n```\n%s````  \n",
		CallMyName(1),
		N,
		CallTrace(1)))
}

// AddFunc 添加函数
func (M *Markdown) AddFunc(value interface{}) {
	run := runtime.FuncForPC(reflect.ValueOf(value).Pointer())
	S := "# 函数: " + run.Name() + "  \n"
	S += "> 内存地址: " + fmt.Sprintf("*%v*", run.Entry()) + "  \n"
	// 输出函数文件
	file, line := run.FileLine(run.Entry())
	S += fmt.Sprintf("> 文件地址: *%v*  \n> 文件行号: *%d*  \n", file, line)
	M.Data.WriteString(S)
}

// AddStruct 添加结构体
func (M *Markdown) AddStruct(value interface{}) {
	// 得到类型
	T := reflect.TypeOf(value)
	V := reflect.ValueOf(value)
	// 返回数据
	S := "# 结构体: " + T.String() + "  \n"
	S += "> # 数据结构  \n"
	S += "> | 定义名 | 类型  | 标签  |  值   |  \n"
	S += "> | :----: | :---: | :---: | :---: | \n"
	// 结构体定义
	for i := 0; i < T.NumField(); i++ {
		// 可导出
		if V.Field(i).CanInterface() {
			m := T.Field(i)
			// 写入数据
			S += fmt.Sprintf("> | %s | *%s* | %s | %v |  \n",
				m.Name,
				strings.Replace(fmt.Sprintf("%v", m.Type), "*", "\\*", -1),
				m.Tag,
				V.Field(i).Interface())
		}
	}
	// 结构体函数
	for i := 0; i < T.NumMethod(); i++ {
		F := T.Method(i)
		S += "> # 结构体函数: " + F.Name + "  \n"
		S += ">> ## 定义: " + fmt.Sprintf("%v", F.Type) + "  \n"
	}
	M.Data.WriteString(S)
}

// SaveFile 保存文件
func (M *Markdown) SaveFile(file string) (bool, error) {
	// 创建文件
	f, err := os.Create(file)
	if err != nil {
		return false, err
	}
	f.Write(M.Data.Bytes())
	f.Close()
	return false, nil
}
